package CloudStorageServlets;

import CloudStorage.*;
import java.io.DataInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class UploadServlet extends HttpServlet
{
   
    /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException
    {
            HttpSession session = request.getSession();

            if ( session.getAttribute("details sent") == null )
            {
                if ( request.getParameter("description") == null || request.getParameter("price") == null )
                {
                    session.removeAttribute("details sent");
                    session.removeAttribute("upload successful");
                    session.setAttribute("upload error", "");
                    response.sendRedirect("upload.jsp");
                    return;
                }
                else
                {
                    session.setAttribute("category", request.getParameter("category"));
                    session.setAttribute("type", request.getParameter("type"));
                    session.setAttribute("description", request.getParameter("description"));
                    session.setAttribute("price", request.getParameter("price"));
                    session.setAttribute("directory", request.getParameter("directory"));
                    session.setAttribute("keywords", request.getParameter("keywords"));

                    session.setAttribute("details sent", "");
                    session.removeAttribute("upload error");
                    response.sendRedirect("upload.jsp");
                }
            }
            else
            {
                try
                {
                    User user = (User)session.getAttribute("user");

                    //to get the content type information from JSP Request Header
                    String contentType = request.getContentType();
                    //here we are checking the content type is not equal to Null and
                    //as well as the passed data from mulitpart/form-data is greater than or
                    //equal to 0
                    if ((contentType != null) && (contentType.indexOf("multipart/form-data") >= 0))
                    {
                        DataInputStream in = new DataInputStream(request.getInputStream());
                        //we are taking the length of Content type data
                        int formDataLength = request.getContentLength();
                        byte dataBytes[] = new byte[formDataLength];
                        int byteRead = 0;
                        int totalBytesRead = 0;
                        //this loop converting the uploaded file into byte code
                        while (totalBytesRead < formDataLength)
                        {
                            byteRead = in.read(dataBytes, totalBytesRead, formDataLength);
                            totalBytesRead += byteRead;
                        }
                        String file = new String(dataBytes);
                        //for saving the file name

                        String saveFile = file.substring(file.indexOf("filename=\"") + 10);
                        saveFile = saveFile.substring(0, saveFile.indexOf("\n"));
                        saveFile = saveFile.substring(saveFile.lastIndexOf("\\") + 1,saveFile.indexOf("\""));
                        int lastIndex = contentType.lastIndexOf("=");
                        String boundary = contentType.substring(lastIndex + 1,contentType.length());
                        int pos;
                        //extracting the index of file
                        pos = file.indexOf("filename=\"");
                        pos = file.indexOf("\n", pos) + 1;
                        pos = file.indexOf("\n", pos) + 1;
                        pos = file.indexOf("\n", pos) + 1;
                        int boundaryLocation = file.indexOf(boundary, pos) - 4;
                        int startPos = ((file.substring(0, pos)).getBytes()).length;
                        int endPos = ((file.substring(0, boundaryLocation)).getBytes()).length;

                        if ( ( (String) session.getAttribute("directory")).equals("Default file-type directory") == true)
                        {

                            String directory = Utility.getPostFix(saveFile);
                            new java.io.File(user.getUsername() + "/" + directory).mkdir();
                            session.setAttribute("directory", directory);
                        }

                        String filename = user.getUsername() + "/" + (String) session.getAttribute("directory") +  "/" + saveFile;
                        FileOutputStream fileOut = new FileOutputStream(filename);
                        fileOut.write(dataBytes, startPos, (endPos - startPos));
                        fileOut.flush();
                        fileOut.close();

                        long s = (new java.io.File(filename)).length();

                        if ( s > user.getAvailableSpace() )
                        {
                            session.setAttribute("cannot upload", "");
                            session.removeAttribute("details sent");
                            session.removeAttribute("upload successful");
                            response.sendRedirect("upload.jsp");

                            java.io.File deleteFile = new java.io.File(filename);
                            deleteFile.delete();

                            return ;
                        }

                        Database database = new Database();
                        CloudStorage.File newFile;

                        newFile = new CloudStorage.File(user.getId(), (String) session.getAttribute("directory") +  "/" +saveFile, (String) session.getAttribute("type"),
                                                     Float.parseFloat( (String) session.getAttribute("price")), (String) session.getAttribute("category"),
                                                    (String) session.getAttribute("description") );
                        database.insertFile(newFile, (String) session.getAttribute("keywords"));
                        
                        database.removeAvailableSpace(user.getId(), totalBytesRead);
                        user = database.getUser(user.getUsername());

                        session.setAttribute("upload successful", "");
                        session.removeAttribute("upload error");
                        session.removeAttribute("details sent");
                        response.sendRedirect("upload.jsp");
                        session.removeAttribute("category");
                        session.removeAttribute("type");
                        session.removeAttribute("description");
                        session.removeAttribute("price");
                        session.removeAttribute("folder");
                    }
                }
                catch(Exception ex)
                {
                    session.removeAttribute("details sent");
                    session.removeAttribute("upload successful");
                    session.setAttribute("upload error", "");
                    response.sendRedirect("upload.jsp");
                }
        }
    } 

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        try {
            processRequest(request, response);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(UploadServlet.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            Logger.getLogger(UploadServlet.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            Logger.getLogger(UploadServlet.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SQLException ex) {
            Logger.getLogger(UploadServlet.class.getName()).log(Level.SEVERE, null, ex);
        }
    } 

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        try {
            processRequest(request, response);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(UploadServlet.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            Logger.getLogger(UploadServlet.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            Logger.getLogger(UploadServlet.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SQLException ex) {
            Logger.getLogger(UploadServlet.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>

}
